package io.renren.common.config;


import io.renren.common.utils.GlobalConstant;
import io.renren.common.utils.HttpClient;
import io.renren.modules.noc.entity.NocMemberEntity;
import io.renren.modules.noc.entity.NocTemplateEntity;
import io.renren.modules.noc.service.NocMemberService;
import io.renren.modules.noc.service.NocTemplateService;
import io.renren.modules.sys.shiro.ShiroUtils;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.session.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by xupeng on 15/8/25.
 * code=041Nfrgp1gTHUo0keLep1Aklgp1NfrgZ
 * &
 * state=123
 * http://iot.com.ngrok.cc/wx/index?code=041Nfrgp1gTHUo0keLep1Aklgp1NfrgZ&state=123
 *
 * 021AOTru11Wwo906HDru11vfsu1AOTr7
 */
@Component
public class WeixinInterceptor implements HandlerInterceptor {

    //会员公众号微信appid
    //@Value("${weixin.appId}")
    //private String appId;
    //会员公众号微信appSecret
    //@Value("${weixin.appSecret}")
    //private String appSecret;
    @Autowired
    private NocTemplateService nocTemplateService;

    /**
     * 微信请求拦截器
     * 1、判断是否是微信端的请求，如果是微信的请求就进入本拦截器，否则退出本拦截器。
     * 2、取出微信用户的openid。
     * 3、根据openid查询用户信息，如有则存入session中。
     * 4、将微信信息存入session中。
     * @param req
     * @param res
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception {
        String header = req.getHeader("User-Agent");

        String backURL = req.getRequestURL().toString();
        //验证码 闸机数据接口直接放行
        if(backURL.contains("/readCard")||backURL.contains("/createImg")||backURL.contains("/error")||backURL.contains("/createQrcode")
                ||backURL.contains("/invite")||backURL.contains("/help")||backURL.contains("/doInvite")||backURL.contains("/doHelp")||backURL.contains("/getCertificate")){
            return true;
        }

        //是否是微信端的请求
        if (StringUtils.isNotBlank(header) && header.contains("MicroMessenger")){
            //防止用户分享后连接参数发送变化，造成新用户无法打开
            //此功能只保留有效参数
            String ly = req.getParameter("ly");
            String tid = req.getParameter("tid");
            if (req.getQueryString() != null) {
                String id = req.getParameter("id");
                backURL += "?tid=" + tid + "&ly="+ly;
                if(StringUtils.isNotEmpty(id)){
                    backURL += "&id="+id;
                }
            }

            NocTemplateEntity template = nocTemplateService.getById(tid);
            String appId = template.getAppid();
            String appSecret = template.getAppsecret();
            //如果没有appId就不拦截
            if(StringUtils.isEmpty(appId)){
                return true;
            }

            String code = req.getParameter("code");
            //从shiro session中取值
            Session session = ShiroUtils.getSession();
            System.out.println(session.getTimeout());
            Map wxUser = (Map)session.getAttribute(GlobalConstant.SESSION_WX_USER);
            if (wxUser != null){
                return true;
            }

            //微信端返回code
            if(code!=null){
                String url = "https://api.weixin.qq.com/sns/oauth2/access_token";
                String param = "appid="+appId+"&secret="+appSecret+"&code="+code+"&grant_type=authorization_code";
                HttpClient client = new HttpClient();
                String result = client.sendGet(url, param);
                JSONObject jsonData = JSONObject.fromObject(result);
                //code失效，需要重新请求
                if (jsonData.has("errcode")){
                    String redirectUrl = getRedirectUrl(appId, backURL);
                    res.sendRedirect(redirectUrl);
                    return false;
                }
                //String access_token=jsonData.getString("access_token");
                String openid = jsonData.getString("openid");
                //String url2 = "https://api.weixin.qq.com/sns/userinfo";
                //String param2 = "access_token="+access_token+"&openid="+openid+"&lang=zh_CN";
                //String result2 = client.sendGet(url2, param2);
                //初始化
                //initSessionIfMember(result2,session);
                initSessionIfMember(openid);
            } else {
                String redirectUrl = getRedirectUrl(appId,backURL);
                res.sendRedirect(redirectUrl);
                return false;
            }
        }
        return true;
    }

    /**
     * 如果是会员用户登录，初始化session信息
     * @param openid
     */
    private void initSessionIfMember(String openid) {
        Map wxUser = new HashMap<String, String>();
        wxUser.put("openId", openid);
        //未绑定（新用户）
        //session.setAttribute(GlobalConstant.SESSION_WX_USER, wxUser);
        //保存到shiro session
        Session session = ShiroUtils.getSession();
        session.setTimeout(60*60*1000);
        session.setAttribute(GlobalConstant.SESSION_WX_USER, wxUser);
    }

    /**
     * 获取微信code
     * @param appId
     * @param wxLogonUrl
     * @return
     */
    private String getRedirectUrl(String appId, String wxLogonUrl){
        try {
            wxLogonUrl = URLEncoder.encode(wxLogonUrl, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        //重定向获取微信auth认证code
        String getCodeUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId
                + "&redirect_uri=" + wxLogonUrl
                + "&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect";
        return getCodeUrl;
    }

    @Override
    public void postHandle(HttpServletRequest req, HttpServletResponse res, Object arg2, ModelAndView arg3) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest req, HttpServletResponse res, Object arg2, Exception arg3) throws Exception {
    }

}
